#region Using Statements
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using XDL.Framework;
#endregion

namespace XDL.Framework.Screens
{
    /// <summary>
    /// Helper class represents a single entry in a <see cref="MenuScreen"/>. By default this
    /// just draws the entry text string, but it can be customized to display menu
    /// entries in different ways. This also provides an event that will be raised
    /// when the menu entry is selected.
    /// </summary>
    public class MenuItem : 
        TextElement
    {
        /// <summary>
        /// Tracks a fading selection effect on the entry.
        /// </summary>
        /// <remarks>
        /// The entries transition out of the selection effect when they are deselected.
        /// </remarks>
        float m_selectionFade;

        #region Events
        /// <summary>
        /// Event raised when the menu entry is selected.
        /// </summary>
        public event EventHandler<EventArgs> Selected;

        /// <summary>
        /// Method for raising the Selected event.
        /// </summary>
        void OnSelectEntry()
        {
            if (Selected != null && Enabled)
                Selected(this, EventArgs.Empty);
        }

        #endregion

        #region Initialization

        /// <summary>
        /// Constructs a new menu entry with the specified text.
        /// </summary>
        /// <param name="text">Menu entry text</param>
        public MenuItem(string text):
            base(text)
        {
        }
        #endregion

        #region Update and Draw

        public override bool Focus()
        {
            return Enabled;
        }

        /// <summary>
        /// Updates the menu entry.
        /// </summary>
        public override void Update(MenuScreen screen, bool isSelected,
                                                      GameTime gameTime)
        {
            // When the menu selection changes, entries gradually fade between
            // their selected and deselected appearance, rather than instantly
            // popping to the new state.
            float fadeSpeed = (float)gameTime.ElapsedGameTime.TotalSeconds * 4;

            if (isSelected)
                m_selectionFade = Math.Min(m_selectionFade + fadeSpeed, 1);
            else
                m_selectionFade = Math.Max(m_selectionFade - fadeSpeed, 0);
        }


        /// <summary>
        /// Draws the menu entry. This can be overridden to customize the appearance.
        /// </summary>
        public override void Draw(MenuScreen screen, Vector2 position,
                                 bool isSelected, GameTime gameTime)
        {
            // text color
            Color color = isSelected ? screen.SelectedTextColor : screen.TextColor;
            if (isSelected)
            {
                // Pulsate the color of the selected menu entry.
                double time = gameTime.TotalGameTime.TotalSeconds;

                float pulsate = (float)Math.Sin(time * 6);

                color = new Color(Vector4.Lerp(screen.SelectedTextColor.ToVector4(), screen.TextColor.ToVector4(), pulsate));
            }
            else
            {
                color = new Color(Vector4.Lerp(screen.SelectedTextColor.ToVector4(), screen.TextColor.ToVector4(), 1-m_selectionFade));
            }

            // Modify the alpha to fade text out during transitions.
            color.A = screen.TransitionAlpha;

            Draw(screen, position, gameTime, color);
        }

        public override void HandleInput(XDL.Framework.Input.InputState input)
        {
            if (input.MenuSelect)
            {
                OnSelectEntry();

                // sound!
                try
                {
                    AudioManager audio = GameServices.GetService<AudioManager>();
                    audio.PlayCue("MenuSelect");
                }
                catch
                {
                    // not critical
                }
            }
        }
        #endregion
    }
}
